<template>
  <a-modal :visible="isShowModal" width="50%" :closable="false" :footer="false">
    <template #title>
      <div class="modal_title">
        <h4>图片剪裁</h4>
        <a-space>
          <a-button size="small" @click="cancel">取消</a-button>
          <a-button size="small" @click="clear">清除</a-button>
          <a-button size="small" @click="reset">重置</a-button>
          <a-button size="small" type="primary" @click="getResult">裁剪</a-button>
        </a-space>
      </div>
    </template>
    <div class="modal-content">
      <VuePictureCropper
        :img="pic"
        @ready="ready"
        :boxStyle="corpBoxStyle"
        :options="corpOptions"
        :presetMode="corpPresetMode"
      />
    </div>
  </a-modal>
</template>

<script setup>
import { reactive, ref, watch, computed } from 'vue'
// 组件文档：https://cropper.chengpeiquan.com/zh/quick-start.html
import VuePictureCropper, { cropper } from 'vue-picture-cropper'
import { PhotoCompress } from '@/utils/compressUtil.js'

const props = defineProps({
  visible: {
    type: Boolean
  },
  image: {
    type: [String, File]
  },
  presetMode: {
    type: Object
  },
  options: {
    type: Object
  },
  boxStyle: {
    type: Object
  },
  showClear: {
    // 是否显示 Clear 按钮
    type: Boolean
  },
  showReset: {
    // 是否显示 Reset 按钮
    type: Boolean
  },
  isCompress: {
    // 是否压缩裁剪后的图片大小
    type: Boolean
  },
  compressSize: {
    // 压缩图片大小限制
    type: Object,
    default: {
      maxSize: 0.3 * 1024 * 1024, // 300k
      minSize: 0.03 * 1024 * 1024 // 30k
    }
  },
  width: {
    type: String,
    default: '300px'
  },
  height: {
    type: String,
    default: '300px'
  }
})

/** 裁剪组件属性配置 */
const corpOptions = computed(() => {
  return {
    viewMode: 1, // 裁剪框范围 1-只能在图片区域内活动
    dragMode: 'move', // 可选值 crop(可绘制裁剪框) | move(仅移动)
    aspectRatio: 1 / 1, // 裁剪框的宽高比
    cropBoxResizable: false, // 是否可以调整裁剪区的大小
    ...props.options
  }
})
/** 裁剪区域的样式 */
const corpBoxStyle = computed(() => {
  return {
    width: props.width,
    height: props.height,
    backgroundColor: '#f8f8f8',
    margin: 'auto',
    ...props.boxStyle
  }
})

/** 预设模式配置 */
const corpPresetMode = computed(() => {
  return {
    mode: 'fixedSize',
    width: 300,
    height: 300,
    ...props.presetMode
  }
})
const emits = defineEmits(['close'])

watch(
  () => props.visible,
  (val) => {
    isShowModal.value = val
    if (!val) {
      pic.value = ''
      result.dataURL = ''
      result.blobURL = ''
      reset()
    }
  }
)

watch(
  () => props.image,
  (val) => {
    pic.value = val
  }
)

const isShowModal = ref(false)
const pic = ref('')
const result = reactive({
  dataURL: '',
  blobURL: ''
})

/**
 * Get cropping results
 */
async function getResult() {
  if (!cropper) return
  const base64 = cropper.getDataURL()
  const blob = await cropper.getBlob()
  if (!blob) return

  let file = await cropper.getFile({
    fileName: 'locales.fileName'
  })

  result.dataURL = base64
  result.blobURL = URL.createObjectURL(blob)
  const { minSize, maxSize } = props.compressSize
  // console.log(file.size, maxSize)
  // 是否限制文件大小
  if (props.isCompress && file.size > maxSize) {
    // console.log("compress")
    const photoCompress = new PhotoCompress(minSize, maxSize)
    photoCompress.compress(file, function (f) {
      const r = new FileReader()
      r.readAsDataURL(f)
      r.onload = function (e) {
        emits('close', { result, file: f })
      }
    })
  } else {
    // console.log("crop")
    emits('close', { result, file })
  }
}

/**
 * Clear the crop box
 */
function clear() {
  if (!cropper) return
  cropper.clear()
}

/**
 * Reset the default cropping area
 */
function reset() {
  if (!cropper) return
  cropper.reset()
}

/**
 * The ready event passed to Cropper.js
 */
function ready() {
  // console.log('Cropper is ready.')
}

function cancel() {
  emits('close')
}
</script>

<style lang="scss" scoped>
.modal_title {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between !important;
}
</style>
